package pl.edu.agh.agents.state;

import java.util.ArrayList;
import java.util.List;

public class Deadlock {
	private State s1;
	private State s2;
	List<State> states;
	private int ID;
	private boolean empty;
	
	public Deadlock(int ID) {
		this.ID = ID;
		this.states = new ArrayList<State>();
		this.empty = true;
	}

	public void setEmpty(boolean empty){
		this.empty = empty;
	}
	
	public boolean isEmpty(){
		return this.empty;
	}
	
	public void setStartOrEnd(State s) {
		if (s1 == null) {
			s1 = s;
		} else {
			s2 = s;
		}
	}
	
	public int getID(){
		return ID;
	}

	public State getBegin(){
		return s1;
	}
	
	public State getEnd(){
		return s2;
	}
	
	public void put(State s){
		states.add(s);
	}
	
	public void put(List<State> states){
		this.states.addAll(new ArrayList<State>(states));
	}
	
	public void remove(int i){
		states.remove(i);
	}
	
	public boolean starts(State s) {
		if (s1.equals(s) || s2.equals(s)) {
			return true;
		}
		return false;
	}

	public boolean contain(State s){
		for (State d : states) {
			if(s.equals(d)){
				return true;
			}
		}
		return false;
	}
	
	public boolean contain(List<State> s){
		int size = s.size();
		if(size>size()){
			return false;
		}
		for (State d : states) {
			if(s.contains(d)){
				size--;
			}
		}
		if(size==0){
			return true;
		}
		return false;
	}
	
	public State getEnd(State s){
		if(s.equals(s1)){
			return s2;
		}
		return s1;
	}
	
	public boolean contains(Object deadlock){
		Deadlock d = (Deadlock) deadlock;
		boolean contains = false;
		boolean containsS1 = false;
		boolean containsS2 = false;
		State start = d.getBegin();
		State end = d.getEnd();
		
		if(starts(start) && starts(end) && d.size()==size()){
			contains = true;
		}
		for (State s : getStates()) {
			if(s.equals(start)){
				containsS1 = true;
			}
			if(s.equals(end)){
				containsS2 = true;
			}
		}
		
		if(containsS1 && containsS2){
			contains = true;
		}
		if(contains){
			for (State s : d.getStates()) {
				if(!states.contains(s)){
					contains=false;
					break;
				}
			}
		}
		
		return contains;
	}
	
	public List<State> getStates(){
		return states;
	}
	
	public int size() {
		return states.size();
	}
	
	public String toString(){
		System.out.println("-----");
		for (State s : states) {
			System.out.println(s.getID());
		}
		System.out.println("-----");
		return s1.getID() + " - " + s2.getID() + " - size: " + size();
	}

	/**
	 * Sprawdza czy agent w deadlocku idzie w moja strone => true, jak false to idziemy w tym samym kierunku wiec moge isc dalej
	 */
	public boolean myDirection(State state, State next, State startState) {
		int startIndex = states.indexOf(startState);
		int currentIndex = states.indexOf(state);
		int nextIndex = states.indexOf(next);
		
		if(currentIndex<nextIndex){
			if(startIndex>currentIndex){
				 return true;
			}
		} else {
			if (startIndex<currentIndex){
				return true;
			}
		}
		return false;
	}
}
